import os
import sys
import shutil
from PyInstaller.__main__ import run

# 设置控制台输出编码为UTF-8
if sys.platform.startswith('win'):
    import io
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')

def clean_build_dirs():
    """清理构建目录"""
    dirs_to_clean = ['build', 'dist']
    for dir_name in dirs_to_clean:
        if os.path.exists(dir_name):
            shutil.rmtree(dir_name)
    spec_files = ['Firmware_Downloader.spec', 'main.spec']
    for spec_file in spec_files:
        if os.path.exists(spec_file):
            os.remove(spec_file)
    print("清理构建目录完成")

def build_exe():
    """构建exe程序"""
    print("开始构建固件下载工具(CAN通信)...")
    
    # 检查主程序文件是否存在
    if not os.path.exists('main.py'):
        print("错误: 未找到main.py主程序文件!")
        sys.exit(1)
    
    # PyInstaller参数
    params = [
        'main.py',                        # 主程序入口
        '--name=Firmware_Downloader',      # 生成的exe名称
        '--noconsole',                    # 不显示控制台窗口
        '--noconfirm',                    # 覆盖已存在的构建目录
        '--clean',                        # 在构建之前清理缓存
        '--onefile',                      # 生成单个exe文件
    ]

    # 添加数据文件
    if os.path.exists('configs'):
        params.append('--add-data=configs;configs')
        print("包含configs配置目录")
    
    if os.path.exists('log'):
        params.append('--add-data=log;log')
        print("包含log日志目录")
    
    # 添加固件文件（如果存在）
    # if os.path.exists('CHLP-GNRC-STM32G0B1CBTx.s19'):
    #     params.append('--add-data=CHLP-GNRC-STM32G0B1CBTx.s19;.')
    #     print("包含示例固件文件")

    # 添加隐藏导入 - 基于项目实际使用的模块
    hidden_imports = [
        # PyQt5相关
        'PyQt5',
        'PyQt5.QtCore',
        'PyQt5.QtGui', 
        'PyQt5.QtWidgets',
        
        # 串口通信
        'serial',
        'serial.tools',
        'serial.tools.list_ports',
        
        # Modbus通信
        'pymodbus',
        'pymodbus.client',
        'pymodbus.framer',
        
        # 标准库模块
        'struct',
        'threading',
        'time',
        'enum',
        'dataclasses',
        'typing',
        'abc',
        'queue',
        'traceback',
        'inspect',
        'logging',
        'datetime',
        
        # 项目模块
        'app',
        'app.gui',
        'app.gui.models',
        'app.gui.views', 
        'app.gui.controllers',
        'app.controller',
        'app.utils',
        'app.dev_com',
    ]
    
    for module in hidden_imports:
        params.append(f'--hidden-import={module}')

    # 添加所有Python模块路径
    python_paths = [
        '.',
        'app',
        'app/gui',
        'app/gui/models',
        'app/gui/views',
        'app/gui/controllers', 
        'app/controller',
        'app/utils',
        'app/dev_com',
    ]
    
    for path in python_paths:
        if os.path.exists(path):
            params.append(f'--paths={path}')

    try:
        # 清理旧的构建文件
        clean_build_dirs()
        
        # 运行PyInstaller
        print("\n开始PyInstaller打包...")
        print(f"使用参数: {' '.join(params)}")
        run(params)
        
        print("\n" + "="*50)
        print("✅ 构建完成!")
        print("📦 可执行文件位置: dist/Firmware_Downloader.exe")
        print("🎯 这是一个固件下载工具")
        print("🔧 支持通过CAN通信进行固件下载")
        print("="*50)
        
    except Exception as e:
        print(f"❌ 构建过程中出现错误: {str(e)}")
        import traceback
        traceback.print_exc()
        sys.exit(1)

if __name__ == '__main__':
    build_exe() 